package org.prowl.torquescan;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import monitor.model.parameter.EcuParameterType;

import org.prowl.torque.remote.ITorqueService;

import org.prowl.torquescan.R;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Color;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.RemoteException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

/**
 * Display ECU parameters in real time and control sending of data to the cloud
 *
 */
public class StartStop extends Activity {

	private ITorqueService torqueService;

	private TextView textView;
	private Button actionButton;
	private Button testModeButton;
	private String carId;
	private Handler handler;
	private NumberFormat nf;
	private final static long UPDATE_INTERVAL_MILLIS = 200;//millis
	private List<EcuParameterType> observedParameters = new ArrayList<EcuParameterType>();
	
	private PowerManager pm;
	private PowerManager.WakeLock wl;
	
	private Timer updateTimer;
	
	private OnClickListener actionButtonListener = new OnClickListener() {
		final String START_MONITORING = "Start monitoring";
		final String STOP_MONITORING = "Stop monitoring";
		
		@Override
		public void onClick(View v) {
			if(actionButton.getText().equals(STOP_MONITORING)) {
				ParameterRepo.stop();
				actionButton.setText(START_MONITORING);
				actionButton.setBackgroundColor(Color.GREEN);
			} else {
				ParameterRepo.setCarId(carId);
				ParameterRepo.start();
				actionButton.setText(STOP_MONITORING);
				actionButton.setBackgroundColor(Color.RED);
			}
		}
	};
	
	private OnClickListener testModeButtonListener = new OnClickListener() {
		@Override
		public void onClick(View v) {
			try {
				torqueService.setDebugTestMode(true);
			} catch (RemoteException e) {
				Log.e(getClass().getCanonicalName(), e.getMessage(), e);
			}
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		Intent intent = getIntent();
		this.carId = intent.getStringExtra("carId");
		if(intent.getBooleanExtra("temperature", false)) {
			this.observedParameters.add(EcuParameterType.TEMPERATURE);
		}
		if(intent.getBooleanExtra("speed", false)) {
			this.observedParameters.add(EcuParameterType.SPEED);
		}
		if(intent.getBooleanExtra("consumption", false)) {
			this.observedParameters.add(EcuParameterType.CONSUMPTION);
		}
		
		LayoutInflater inflater = LayoutInflater.from(this);
		View view = inflater.inflate(R.layout.main, null);
		textView = (TextView)view.findViewById(R.id.textview);
		
		actionButton = (Button)view.findViewById(R.id.actionButton);
		actionButton.setOnClickListener(actionButtonListener);
		
		testModeButton = (Button)view.findViewById(R.id.testModeButton);
		testModeButton.setOnClickListener(testModeButtonListener);

		// Max of 2 digits for readings.
		nf = NumberFormat.getInstance();
		nf.setMaximumFractionDigits(2);

		handler = new Handler();

		setContentView(view);
		
		pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
		wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
		LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
		ParameterRepo.setLocationManager(locationManager);
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		wl.release();
		if(updateTimer != null) {
			updateTimer.cancel();
		}
		unbindService(connection);
		ParameterRepo.stop();
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		wl.acquire();
		
		Intent intent = new Intent();
		intent.setClassName("org.prowl.torque",	"org.prowl.torque.remote.TorqueService");
		boolean successfulBinded = bindService(intent, connection, 0);

		if (successfulBinded) {
			updateTimer = new Timer();
			updateTimer.schedule(new TimerTask() {
				public void run() {
					update();
				}
			}, 1000, UPDATE_INTERVAL_MILLIS);
		}
	}
	
	/**
	 * Update screen with newly obtained ECU data
	 */
	public void update() {
		StringBuilder text = new StringBuilder();

		try {
			text.append("-------------------------------\n");
			text.append("CAR ID:" + this.carId + "\n");
			text.append("-------------------------------\n");
			text.append("OBSERVED PARAMETERS LIVE VIEW:\n");
			for (EcuParameterType parameter : observedParameters) {
				long pid =  parameter.getPid();
				float value = torqueService.getValueForPid(pid, true);
				ParameterRepo.addParameter(parameter, value);
				String pidDescription = torqueService.getDescriptionForPid(pid);
				String dimension = torqueService.getUnitForPid(pid);
				text.append(pidDescription + ":" + value + " " + dimension + "\n");
			}
			text.append("-------------------------------\n");
		} catch (RemoteException e) {
			Log.e(getClass().getCanonicalName(), e.getMessage(), e);
		}

		// Update the widget.
		final String myText = text.toString();
		handler.post(new Runnable() {
			public void run() {
				textView.setText(myText);
			}
		});
	}

	/**
	 * bind to Torque AIDL service
	 */
	private ServiceConnection connection = new ServiceConnection() {
		public void onServiceConnected(ComponentName arg0, IBinder service) {
			torqueService = ITorqueService.Stub.asInterface(service);
		};

		public void onServiceDisconnected(ComponentName name) {
			torqueService = null;
		};
	};
}